package rpc.netty.server;

import com.alibaba.fastjson2.JSONArray;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.SimpleChannelInboundHandler;
import rpc.common.MyMessageProtocol;
import rpc.register.MyLocalRegister;

import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.nio.charset.StandardCharsets;
import java.util.List;

/**
 * 自定义服务端处理器
 */
public class MyServerHandler extends SimpleChannelInboundHandler<MyMessageProtocol> {
    /**
     * 通道读取
     */
    @Override
    protected void channelRead0(ChannelHandlerContext channelHandlerContext, MyMessageProtocol myMessageProtocol) throws NoSuchMethodException, InvocationTargetException, InstantiationException, IllegalAccessException {
        String content = new String(myMessageProtocol.getContent(), StandardCharsets.UTF_8);
        System.out.println("接收消息：" + content);
        String[] contents = content.split("#");
        String interfaceName = contents[0];
        String methodName = contents[1];
        List<Object> parameterTypeList = JSONArray.parseArray(contents[2]);
        Class<?>[] parameterTypes = new Class<?>[parameterTypeList.size()];
        for (int i = 0; i < parameterTypeList.size(); i++) {
            parameterTypes[i] = parameterTypeList.get(i).getClass();
        }

        List<Object> parameters = JSONArray.parseArray(contents[3]);
        //从本地注册获取接口实现类
        Class<?> classImpl = MyLocalRegister.get(interfaceName);
        //从实现类获取方法
        Method method = classImpl.getMethod(methodName, parameterTypes);
        //获取实现类对象
        Object object = classImpl.getDeclaredConstructor().newInstance();
        //执行方法获取返回参数
        String result = (String) method.invoke(object, parameters.toArray());

        String resultContent = content + "#" + result;
        byte[] resultContentByte = resultContent.getBytes(StandardCharsets.UTF_8);
        myMessageProtocol.setLength(resultContentByte.length);
        myMessageProtocol.setContent(resultContentByte);

        //写入返回内容
        channelHandlerContext.write(myMessageProtocol);
        //刷新
        channelHandlerContext.flush();
    }
}
